use super::{enhanced_array::EnhancedArray, tools};

//// LFSR 线性反馈移位寄存器.
#[derive(Debug)]
pub struct Lfsr {
    // 16个31位的寄存器.
    s: EnhancedArray<u32, 16>,
}

impl Lfsr {
    /// 使用初始化好的s数组构建.
    pub fn with_array(s: [u32; 16]) -> Self {
        Self {
            s: EnhancedArray::with_array(s),
        }
    }

    /// 获取寄存器组s.
    pub fn get_s(&self) -> &EnhancedArray<u32, 16> {
        &self.s
    }

    /// 初始化模式.
    ///
    /// 参数为31比特字 u = W >> 1.
    pub fn lfsr_with_initialization_mode(&mut self, u: u32) {
        let v = [
            tools::left_mod_2_31_dec1(*self.s.get(15), 15),
            tools::left_mod_2_31_dec1(*self.s.get(13), 17),
            tools::left_mod_2_31_dec1(*self.s.get(10), 21),
            tools::left_mod_2_31_dec1(*self.s.get(4), 20),
            tools::left_mod_2_31_dec1(*self.s.get(0), 8),
            *self.s.get(0),
        ]
        .into_iter()
        .fold(0, |acc, x| tools::add_mod_2_31_dec1(acc, x));
        // let v = v % ((1 << 31) - 1);
        // 如果v取模过了的话, 这里的31位加法取模可以使用位运算加速.
        let mut new_num = tools::add_mod_2_31_dec1(u, v);
        if new_num == 0 {
            new_num = 1 << 31 - 1;
        }
        self.s.left_move(new_num);
    }

    /// 工作模式.
    pub fn lfsr_with_work_mode(&mut self) {
        self.lfsr_with_initialization_mode(0);
    }
}
